package com.yy.service.impl;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;

import com.yy.common.constant.PmsConstants;
import com.yy.common.exception.ServiceException;
import com.yy.common.utils.SecurityUtils;
import com.yy.domain.*;
import com.yy.mapper.*;
import com.yy.service.IPayOrderService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import javax.annotation.Resource;

/**
 * 订单管理Service业务层处理
 *
 * @author yy
 * @date 2023-10-31
 */
@Service
public class PayOrderServiceImpl implements IPayOrderService {
    @Resource
    private PayOrderMapper payOrderMapper;

    @Resource
    private PayContractMapper payContractMapper;

    @Resource
    private PayContractFeeMapper payContractFeeMapper;

    @Resource
    private AssetHouseMapper assetHouseMapper;

    @Resource
    private PayFeeItemMapper payFeeItemMapper;


    /**
     * 查询订单管理列表
     *
     * @param payOrder 订单管理
     * @return 订单管理
     */
    @Override
    public List<PayOrder> selectPayOrderList(PayOrder payOrder) {
        return payOrderMapper.selectPayOrderList(payOrder);
    }

    /**
     * 添加收费项目创建订单
     * 目地: 把数据整理好。保存到pay_order
     * 1.把数据保存到pay_order
     * 2.把pay_contract_fee里面的下次缴费时间后推(根据收费项目的收费周期后推) ---查询收费项目的数据
     *
     * @param contractId 合同ID
     * @param ids        要生成的收费项目的ID
     * @return
     */
    @Override
    public int addOrderNormal(Long contractId, Long[] ids) {
        //根据合同Id合同信息
        PayContract contract = payContractMapper.selectPayContractById(contractId);
        if (ObjectUtils.isEmpty(contract)) {
            throw new ServiceException("合同不存在");
        }
        //根据商铺ID获取商铺信息
        AssetHouse assetHouse = assetHouseMapper.selectAssetHouseById(contract.getHouseId());
        if (ObjectUtils.isEmpty(assetHouse)) {
            throw new ServiceException("合同对应的商铺不存在");
        }
        //判断ids是否为空
        if (ids == null || ids.length == 0) {
            throw new ServiceException("收费项目ID不能为空");
        }
        //根据收费项目ID查询收费项目的数据
        List<PayFeeItem> payFeeItems = this.payFeeItemMapper.selectPayFeeItemByIds(Arrays.asList(ids));
        //把 List<PayFeeItem> 转成itemID---item
        Map<Long,PayFeeItem> payFeeItemMap=payFeeItems.stream().collect(Collectors.toMap(PayFeeItem::getId,payFeeItem -> payFeeItem));
        //根据收费项目的ID和合同Id查询出当前合同的收费项目
        List<PayContractFee> payContractFees = this.payContractFeeMapper.queryContractFeeItemByContractIdAndFeeItemIds(contractId, ids);
        int row=0;
        for (PayContractFee payContractFee : payContractFees) {
            //取出收费项目详情
            PayFeeItem payFeeItem = payFeeItemMap.get(payContractFee.getFeeItemId());
            //保存payOrder
            PayOrder payOrder=new PayOrder();
            payOrder.setOrderId(IdUtil.getSnowflakeNextIdStr());
            payOrder.setContractId(contract.getId());
            payOrder.setPayState(PmsConstants.PAY_ORDER_STATE_0);//订单创建
            payOrder.setHouseId(assetHouse.getId());
            payOrder.setCreateBy(SecurityUtils.getUsername());
            payOrder.setCreateTime(new Date());
            payOrder.setBeginTime(payContractFee.getNextBillDate());
            //计算结束时间
            Date endTime = DateUtil.offsetMonth(payContractFee.getNextBillDate(), Integer.valueOf(payFeeItem.getPeriod()));
            payOrder.setEndTime(endTime);
            //更新payContractFee的下次收费时间
            payContractFee.setNextBillDate(endTime);
            payContractFee.setTimes(payContractFee.getTimes() + 1);
            this.payContractFeeMapper.updatePayContractFee(payContractFee);
            payOrder.setItemName(payFeeItem.getName());
            payOrder.setNum(Long.valueOf(payFeeItem.getPeriod()));
            payOrder.setPrice(payFeeItem.getPrice());
            ctlAmt(contract, assetHouse, payFeeItem, payOrder);
            row+=this.payOrderMapper.insertPayOrder(payOrder);
        }

        return row;
    }

    @Override
    public List<PayOrder> queryPayOrderByContractCode(String code) {
        return this.payOrderMapper.queryPayOrderByContractCode(code);
    }

    /**
     * 算每一项的总金额
     * @param contract
     * @param assetHouse
     * @param payFeeItem
     * @param payOrder
     */
    private void ctlAmt(PayContract contract, AssetHouse assetHouse, PayFeeItem payFeeItem, PayOrder payOrder) {
        switch (payFeeItem.getNumType()){
            case PmsConstants.FEE_ITEM_NUM_TYPE_FLAT: //按户数收费   价格*户数*周期
                payOrder.setAmt(payFeeItem.getPrice().multiply(new BigDecimal(payFeeItem.getPeriod())));
                break;
            case PmsConstants.FEE_ITEM_NUM_TYPE_PEOPLE://按人口数收费
                break;
            case PmsConstants.FEE_ITEM_NUM_TYPE_FLOOR: //按楼层收费
                break;
            case PmsConstants.FEE_ITEM_NUM_TYPE_BUILDING_AREA: //按占地面积收费
                payOrder.setAmt(payFeeItem.getPrice().multiply(new BigDecimal(payFeeItem.getPeriod())).multiply(assetHouse.getBuildingSquare()));
                break;
            case PmsConstants.FEE_ITEM_NUM_TYPE_USE_AREA: //按使用面积收费
                payOrder.setAmt(payFeeItem.getPrice().multiply(new BigDecimal(payFeeItem.getPeriod())).multiply(assetHouse.getUseSquare()));
                break;
            case PmsConstants.FEE_ITEM_NUM_TYPE_METER: //按走表数量
                break;
            case PmsConstants.FEE_ITEM_NUM_TYPE_RENT_FEE: //按租金收费   ==合同金额*缴费周期
                payOrder.setPrice(contract.getRentFee());
                payOrder.setAmt(contract.getRentFee().multiply(new BigDecimal(payFeeItem.getPeriod())));
                break;
        }
    }
}
